/**
 *Copyright (c) 2024 watereyes
 * workflow is licensed under Mulan PubL v2.
 * You can use this software according to the terms and conditions of the Mulan
 * PubL v2.
 * You may obtain a copy of Mulan PubL v2 at:
 *          http://license.coscl.org.cn/MulanPubL-2.0
 * THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND,
 * EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT,
 * MERCHANTABILITY OR FIT FOR A PARTICULAR PURPOSE.
 * See the Mulan PubL v2 for more details.
 */
package com.koron.workflow.api.cmd;

import java.util.Collection;

import org.activiti.engine.ActivitiException;
import org.activiti.engine.delegate.BpmnError;
import org.activiti.engine.impl.bpmn.behavior.AbstractBpmnActivityBehavior;
import org.activiti.engine.impl.bpmn.behavior.SequentialMultiInstanceBehavior;
import org.activiti.engine.impl.pvm.delegate.ActivityExecution;
import org.activiti.engine.impl.pvm.process.ActivityImpl;

public class MySequentialMultiInstanceBehavior extends SequentialMultiInstanceBehavior {

	/**
	 * 
	 */
	private static final long serialVersionUID = -467645442773200112L;

	// 添加了一个是否加签信号
	Boolean counterSignAdd = false;

	public MySequentialMultiInstanceBehavior(ActivityImpl activity, AbstractBpmnActivityBehavior innerActivityBehavior,
			Boolean counterSignAdd) {
		super(activity, innerActivityBehavior);
		this.counterSignAdd = counterSignAdd;
	}

	@SuppressWarnings("rawtypes")
	@Override
	public void leave(ActivityExecution execution) {
		// 主要修改这里
		Collection collection = (Collection) collectionExpression.getValue(execution);
		int loopCounter = getLoopVariable(execution, getCollectionElementIndexVariable()) + 1;
		int nrOfInstances = getLoopVariable(execution, NUMBER_OF_INSTANCES);
		int nrOfCompletedInstances = getLoopVariable(execution, NUMBER_OF_COMPLETED_INSTANCES) + 1;
		int nrOfActiveInstances = getLoopVariable(execution, NUMBER_OF_ACTIVE_INSTANCES);
		// 如果加签则修改流程变量，主要是修改总数和完成数，然后就没了
		if (counterSignAdd) {
			loopCounter = nrOfCompletedInstances - 1;
			nrOfInstances = collection.size();
			nrOfCompletedInstances = nrOfCompletedInstances - 1;
			counterSignAdd = false;
		}
		if (loopCounter != nrOfInstances && !completionConditionSatisfied(execution)) {
			callActivityEndListeners(execution);
		}

		setLoopVariable(execution, NUMBER_OF_INSTANCES, nrOfInstances);
		setLoopVariable(execution, getCollectionElementIndexVariable(), loopCounter);
		setLoopVariable(execution, NUMBER_OF_COMPLETED_INSTANCES, nrOfCompletedInstances);
		logLoopDetails(execution, "instance completed", loopCounter, nrOfCompletedInstances, nrOfActiveInstances,
				nrOfInstances);

		if (loopCounter >= nrOfInstances || completionConditionSatisfied(execution)) {
			super.leave(execution);
		} else {
			try {
				executeOriginalBehavior(execution, loopCounter);
			} catch (BpmnError error) {
				// re-throw business fault so that it can be caught by an Error Intermediate
				// Event or Error Event Sub-Process in the process
				throw error;
			} catch (Exception e) {
				throw new ActivitiException("Could not execute inner activity behavior of multi instance behavior", e);
			}
		}
	}
}
